<template>
  <div class="elementTable">
    <header>
      <slot name="search" />
      <slot name="header" />
    </header>
    <main v-loading="tabConfig.loading">
      <el-table
          ref="elTable"
          :data="tableData"
          :size="tabConfig.size"
          :stripe="tabConfig.stripe"
          :max-height="tabConfig['max-height']"
          :height="tabConfig.height"
          :border="tabConfig.border"
          :fit="tabConfig.fit"
          :show-header="tabConfig['show-header']"
          :current-row-key="tabConfig['current-row-key']"
          :row-key="tabConfig.rowKey"
          :default-expand-all="defaultExpandAll"
          :header-cell-class-name="headerCellClassName"
          :header-cell-style="headerCellStyle"
          :cell-style="cellStyle"
          :highlight-current-row="highlightCurrentRow"
          :tree-props="tabConfig.treeProps"
          :row-class-name="rowClassName"
          @selection-change="changeSelect"
          @row-click="rowClick"
          @select="select"
          @select-all="selectAll"
      >
        <el-table-column v-if="tabConfig.type" :type="tabConfig.type" />
        <el-table-column
            v-for="item in tableLabel"
            :key="item.prop"
            show-overflow-tooltip
            :column-key="item.prop"
            :prop="item.prop"
            :label="item.label"
            :align="item.align ? item.align: 'center'"
            :width="item.width ? item.width : 'auto'"
        >
          <template slot-scope="scope">
            <slot v-if="item.template" :name="item.prop" :row="scope.row" />
            <span v-else>{{ scope.row[item.prop] }}</span>
          </template>
        </el-table-column>
        <el-table-column
            v-if="tabConfig.edit"
            :label="tabConfig.editLabel"
            :width="tabConfig.editWidth"
            :align="tabConfig.editAlign"
        >
          <template slot-scope="scope">
            <slot name="edit" :row="scope.row" />
          </template>
        </el-table-column>
      </el-table>
      <el-pagination
          v-if="noPaging"
          class="pager"
          background
          layout="total, sizes, prev, pager, next, jumper"
          :total="query.total"
          :current-page.sync="query.pageNumber"
          :page-size="query.pageSize"
          :page-sizes="[pageSize, pageSize * 2, pageSize * 3, pageSize * 4]"
          @size-change="changePageSize"
      />
    </main>
  </div>
</template>
<script>
import axios from "axios";
// 防抖节流
function debounce(func, wait = 1000){
  let timeout;
  return function(event){
    clearTimeout(timeout)
    timeout = setTimeout(()=>{
      func.call(this, event)
    },wait)
  }
}
export default {
  name: 'elementTable',
  props: {
    tableData: { type: Array, default: () => { return [] } },
    tableLabel: { type: Array, default: () => { return [] } },
    defaultExpandAll: { type: Boolean, default: false },
    noPaging: { type: Boolean, default: true },
    highlightCurrentRow: { type: Boolean, default: false },
    rowClassName: { type: Function | String, require: true },
    headerCellClassName: { type: Function | String, require: true },
    headerCellStyle: { type: Function | Object, require: true },
    cellStyle: { type: Function | Object, require: true },
    config: { type: Object, default: () => { return {} } },
    api: {
      type: Object,
      default: () =>{
        return {
          method: 'post',
          url: '',
          token: ''
        }
      }
    },
    query: {
      type: Object,
      default: () => {
        return {
          total: 0,
          pageNumber: 1,
          pageSize: 10
        }
      }
    },
    search: { type: Boolean,  default: true },
    redefineReq: { type: Boolean,  default: true }
  },
  data() {
    return {
      pageSize: null,
      resetNum: 0
    }
  },
  computed: {
    elTable() {
      return this.$refs['elTable']
    },
    tabConfig(){
      return {
        loading: false,
        type: 'selection',
        treeProps: { },
        rowKey: '',
        edit: true,
        editLabel: '操作',
        editWidth: '',
        editAlign: 'center',
        ...this.config
      }
    }
  },
  watch: {
    // 默认直接搜索
    query: {
      handler: function() {
        if (this.search) {
          // 防抖节流
          this.throttle({ vm: this, api: this.api, query: this.query });
        }
      },
      deep: true
    }
  },
  created() {
    this.pageSize = this.query.pageSize
    if (this.redefineReq) {
      this.api.url === '' ? console.error(`was not found in api module`) : this.tabList(this.api, this.query)
    }else {
      this.tabList(this.api, this.query)
    }
  },
  methods: {
    // 数据
    async tabList(api, query) {
      // 默认值添加token
      axios.defaults.headers['Authorization'] = `Bearer ${api.token}`
      this.$emit('funAjax', axios.defaults)
      // 默认传递数据
      if (this.redefineReq) {
        await axios[api.method](api.url, query).then(res =>{
          this.$emit('tabList', res.data, query, this.tabConfig)
        }).catch(() => {  this.tabConfig.loading = false })
      }else {
        // 自定义数据接口
        this.$emit('tabList', api, query, this.tabConfig)
      }
    },
    // 节流数据
    throttle: debounce(({ vm, api, query }) => {
      if (vm.redefineReq) {
        api.url === '' ? console.error(`was not found in api module`) : vm.tabList(api, query)
      }else {
        vm.tabList(api, query)
      }
    }, 300),
    // 复选
    changeSelect(val) {
      this.$emit('changeSelect', val)
    },
    // 点击行
    rowClick(row, column, event) {
      this.$emit('rowClick', row, column, event)
    },
    // 当选数据行触发的事件
    select(selection, row) {
      this.$emit('select', selection, row)
    },
    // 当勾选全选时触发的事件
    selectAll(selection) {
      this.$emit('selectALL', selection)
    },
    // 重置
    reset() {
      this.resetNum++
      this.tabList(this.api, this.query)
    },
    // 每页多少条
    changePageSize(pageSize) {
      this.query.pageSize = pageSize
    }
  }
}
</script>

<style lang="scss" scoped>
.elementTable{
  height: calc(100% - 20px);
  background-color: #ffffff;
  position: relative;
  cursor: pointer;
  header{
    padding: 5px 10px 10px 0;
  }
  .pager {
    padding: 25px 0 10px 0;
    text-align: right;
  }
  // 关闭全选功能
  ::v-deep .closeCheckAll .el-checkbox{
    display: none !important;
  }
}
</style>
